package cn.com.bluemoon.daps.common.toolkit;

import cn.com.bluemoon.daps.common.enums.DatabaseType;
import cn.hutool.core.map.MapUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Jarod.Kong
 */
@Slf4j
public class DbTypeHelper {
    private static final Map<DatabaseType, DbType> dbTypes = new HashMap<DatabaseType, DbType>() {{
        put(DatabaseType.MYSQL, DbType.mysql);
        put(DatabaseType.PGSQL, DbType.postgresql);
        put(DatabaseType.HIVE, DbType.hive);
        put(DatabaseType.POSTGRESQL, DbType.postgresql);
        put(DatabaseType.HBASE, DbType.hbase);
        put(DatabaseType.PHOENIX, DbType.phoenix);
        put(DatabaseType.ES, DbType.elastic_search);
        put(DatabaseType.ELASTICSEARCH, DbType.elastic_search);
        put(DatabaseType.DORIS_DB, DbType.doris_db);
        put(DatabaseType.IMPALA, DbType.impala);
    }};

    private static final Map<DbType, DatabaseType> db2Dt = MapUtil.inverse(dbTypes);

    public static DatabaseType getDatabaseType(DbType dbType) {
        return db2Dt.get(dbType);
    }

    public static DatabaseType getDatabaseType(com.alibaba.druid.DbType druidDbType) {
        DbType dbType = DbType.from(druidDbType);
        return db2Dt.get(dbType);
    }

    public static com.alibaba.druid.DbType getDruidDbType(DatabaseType type) {
        return getDruidDbType(type, null);
    }

    /**
     * 可为null
     */
    public static com.alibaba.druid.DbType getDruidDbType(DatabaseType type, com.alibaba.druid.DbType defaultDbType) {
        DbType dbType = dbTypes.get(type);
        com.alibaba.druid.DbType db = com.alibaba.druid.DbType.of(dbType.name());
        if (db == null) {
            return defaultDbType;
        }
        return db;
    }

    public static DbType getDbType(DatabaseType type) {
        return dbTypes.get(type);
    }

    public static DbType getDbProtocolActualDbType(DatabaseType type) {
        return getDbProtocolActualDbType(DbType.valOf(type));
    }

    public static DbType getDbProtocolActualDbType(String dbName) {
        return getDbProtocolActualDbType(DbType.valOf(dbName));
    }

    /**
     * 实际数据源对应的连接协议
     */
    public static DbType getDbProtocolActualDbType(DbType dbType) {
        if (dbType == null) {
            return null;
        }
        // 目前只支持phoenix jdbc查询
        if (DbType.hbase.equals(dbType) || DbType.phoenix.equals(dbType)) {
            return DbType.phoenix;
        }
        // dorisDB
        if (DbType.doris.equals(dbType) || DbType.doris_db.equals(dbType) || DbType.starrocks.equals(dbType)) {
            return DbType.mysql;
        }
        return dbType;
    }

    /**
     * 数据库类型对应的SQL解析数据库类型
     */
    public static com.alibaba.druid.DbType getSqlParserDruidTypeByDbType(DbType dbType) {
        try {
            if (dbType == null) {
                return null;
            }
            if (DbType.doris_db.equals(dbType) || DbType.doris.equals(dbType) || DbType.starrocks.equals(dbType)) {
                return com.alibaba.druid.DbType.mysql;
            }
            return DbType.of(dbType);
        } catch (Exception e) {
            log.error("数据库类型转为为Druid DbType异常，默认使用MySQL语法检查", e);
        }
        return com.alibaba.druid.DbType.mysql;
    }

}
